function sumSubarrayMins(arr: number[]): number {
    /*
    ? 思路是：找到每个元素的覆盖范围  覆盖范围当然分左右 需要找到左右边界(左边第一个小的和右边第一个小的)
    ? 那么子数组的左边界应该在[left,i]中选取，子数组的右边界应该在[i,right]中选取。因此子数组个数为(i -left + 1) * (right - i + 1)
     */
    let mod = 1e9 + 7;
    //? 维护一个栈
    let stack = [];
    //? 求以A[i]为最小值的子数组左边大于或等于自己的个数
    let prev = [];
    for (let i = 0; i < arr.length; i++) {
        while (stack.length && arr[stack[stack.length - 1]] >= arr[i]) stack.pop();
        //? 如果栈为空，即左边都比自己大，则返回i+1，否则返回i-栈顶元素（即保存的下标值）
        prev[i] = stack.length ? i - stack[stack.length - 1] : i + 1;
        stack.push(i);
    }
    stack = [];
    //? 求以A[i]为最小值的子数组右边大于自己的个数（没有等号是因为不会重复计算相等的值）
    let nextv = [];
    for (let i = arr.length - 1; i >= 0; i--) {
        while (stack.length && arr[stack[stack.length - 1]] > arr[i]) stack.pop();
        //? 如果栈为空，即右边都比自己大，则返回A.length-i，否则返回栈顶元素（即保存的下标值）-i
        nextv[i] = stack.length ? stack[stack.length - 1] - i : arr.length - i;
        stack.push(i);
    }
    let sum = 0;
    for (let i = 0; i < arr.length; i++) {
        //? 以A[i] 为最小值的子数组的组合共有prev[i]*nextv[i]种情况，那么和的话乘以A[i]累加即可
        sum += prev[i] * nextv[i] * arr[i];
        //? 按题意，进行取模运算
        sum %= mod;
    }
    return sum;
};
